package com.apestech.api.condition;

import com.apestech.framework.db.SqlSession;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.modul.FromList;
import com.apestech.framework.sql.modul.SqlStru;
import com.apestech.framework.util.LocalVariable;
import com.apestech.framework.xml.plugin.modul.SysCondition;

public class ConditionField {
    private SqlSession session;
    private String field;
    private String name;
    private String auxiliaryField;
    private String auxiliaryName;
    private String osql;
    private String asql;
    private String sql1;
    private String sql2;
    private String osql1;
    private String osql2;
    private String alias;
    private String nalias;
    private String subSelect;
    private SysCondition sysCondition;
    private FromList from;
    private String role;
    private String roleType;
    private JSONObject nameJson=new JSONObject();;
    private JSONObject idJson=new JSONObject();;

    public ConditionField(String field, SqlSession session, String purpose) throws Exception {
        this.session=session;
        this.field=field;
        sysCondition= LocalVariable.getConfig().getSysCondition(session);
        JSONObject m= sysCondition.getDimensionField(field);
        name=m.getString("name");
        if(name==null){
            name=m.getString("comment");
        }
        String copyField=m.getString("copyField");
        if(purpose!=null){
            JSONObject rm=sysCondition.getRolefield(field);
            if(rm==null && copyField!=null){
                rm=sysCondition.getRolefield(copyField);
            }
            if(rm!=null){
                //pp_belong pp_search pp_operate
                int pos=field.indexOf(".");
                String f;
                if(pos<0){
                    f=field;
                } else {
                    f=field.substring(pos+1, field.length());
                }
                role="<auth field=\""+f+"\" type=\""+rm.getString("type")+"\" purpose=\""+purpose+"\" exp=\""+f+"\"  />";
                roleType=rm.getString("type");
            }
        }
        osql=m.getString("sql");
        asql=osql.toUpperCase();
        int pos=osql.indexOf("sysKey");
        for(int i=pos; i>=0; i--){
            String s=osql.substring(i-1,i);
            if(s.equals("<")){
                osql1=osql.substring(0, i-1);
                osql2=osql.substring(osql.indexOf("</if>",i)+5,osql.length());
                sql1=osql1.toUpperCase();
                sql2=osql2.toUpperCase();
                break;
            }
        }
        auxiliaryField=m.getString("auxiliaryField");
        pos=auxiliaryField.indexOf(",");
        if(pos>=0){
            auxiliaryField=auxiliaryField.substring(0, pos);
        }
        auxiliaryField=auxiliaryField.toUpperCase();
        auxiliaryName=m.getString("auxiliaryName");
        if(auxiliaryName==null){
            auxiliaryName=name+"名称";
        }
        pos=auxiliaryName.indexOf(",");
        if(pos>=0){
            auxiliaryName=auxiliaryName.substring(0, pos);
        }
    }

    public String getSubSelect(String key, String colName, String ftabName, String falias) throws Exception {
        getSubSelect();
        if(ftabName!=null){
            int inx=0;
            int len=from.size();
            for(int i=0; i<len; i++){
                if(from.getTable(i).equals(ftabName)){
                    inx=i;
                    break;
                }
            }
            nameJson.put("field", colName+"_"+auxiliaryField);
            nameJson.put("title", auxiliaryName);
            idJson.put("field", colName);
            idJson.put("title", name);
            return "("+subSelect+" AND S"+inx+"."+key+"="+falias+"."+colName+" ) AS "+colName+"_"+auxiliaryField;
        } else {
            return null;
        }
    }

    public String getSubSelect() throws Exception {
        if(subSelect==null){
            SqlStru sqlStru=new SqlStru(sql1);
            sqlStru.getFrom();
            String from=sqlStru.getFromStr();
            int pos1=sql1.indexOf("SELECT ");
            int pos2=sql1.indexOf(from);  //  lastIndexOf"FROM"
            int pos=sql1.indexOf(auxiliaryField);
            String select="";
            for(int i=pos; i>=0; i--){
                String s=sql1.substring(i-1,i);
                if(" ".equals(s) || ",".equals(s)){
                    select=sql1.substring(i, pos+auxiliaryField.length()).trim()+" ";
                    alias=sql1.substring(i,pos-1);
                    break;
                }
            }
            String osub=osql1.substring(0, pos1+7)+select+osql1.substring(pos2, osql1.length())+osql2;
            subSelect=getSqlNewAlias(osub);
        }
        return subSelect;
    }

    private String getSqlNewAlias(String osub) throws Exception {
        String sub=osub;
        sub=sub.replace("select ", "SELECT ");
        sub=sub.replace("from ", "FROM ");
        sub=sub.replace("where ", "WHERE ");
        int pos2=sub.indexOf("FROM ");
        int pos3=sub.indexOf("WHERE ");
        String subfrom=sub.substring(pos2+5, pos3);
        String subSelect=sub.substring(0, pos2);
        String subWhere=sub.substring(pos3, sub.length());
        from=new FromList(subfrom, null, session);
        int len=from.size();
        for(int i=0; i<len; i++){
            if(from.getAlias(i).equals(alias)){
                nalias="S"+i;
            }
            subSelect=subSelect.replace(from.getAlias(i)+".", "S"+i+".");
            subfrom=subfrom.replace(" "+from.getAlias(i)+" ", " S"+i+" ");
            subfrom=subfrom.replace(" "+from.getAlias(i)+",", " S"+i+",");
            subWhere=subWhere.replace(from.getAlias(i)+".", "S"+i+".");
        }
        String r=subSelect+sub.substring(pos2, pos2+5)+subfrom+subWhere;
        return r;
    }

    public String getRole() {
        return role;
    }

    public String getRoleType() {
        return roleType;
    }

    public JSONObject getNameJson() {
        return nameJson;
    }

    public JSONObject getIdJson() {
        return idJson;
    }
}
